<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    // Set结构的实例与数组一样 也拥有forEach方法 用于对每个成员执行某种操作 没有返回值
    let set = new Set([1, 4, 9]);
    set.forEach((value, key) => console.log(key + ' : ' + value + 1))
    // 1 : 1
    // 4 : 4
    // 9 : 9


    // forEach方法的参数就是一个处理函数 该函数的参数与数组的forEach一致 依次为键值 键名 集合本身
    // 注意: Set结构的键名就是键值(同一个值) 第一个参数与第二个参数的值永远都是一样的


    // 遍历的应用
    // 扩展运算符(...)内部使用for...of循环 所以也可以用于Set结构
    let set = new Set(['red', 'green', 'blue']);
    let arr = [...set];
    // ['red', 'green', 'blue']


    // 扩展运算符和Set结构相结合 可以去除数组的重复成员
    let arr = [3, 5, 2, 2, 5, 5];
    let unique = [...new Set(arr)];
    // [3, 5, 2]


    // 数组的 map 和 filter 方法也可以间接用于Set

    let set = new Set([1, 2, 3]);
    set = new Set([...set].map(x => x * 2));
    // 返回Set结构：{2, 4, 6}

    let set = new Set([1, 2, 3, 4, 5]);
    set = new Set([...set].filter(x => (x % 2) == 0));
    // 返回Set结构：{2, 4}


    // 因此Set可以很容易地实现 并集(Union) 交集(Intersect) 差集(Difference)
    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);

    // 并集
    let union = new Set([...a, ...b]);
    // Set {1, 2, 3, 4}

    // 交集
    let intersect = new Set([...a].filter(x => b.has(x)));
    // set {2, 3}

    // 差集
    let difference = new Set([...a].filter(x => !b.has(x)));
    // Set {1}


    // 如果想在遍历操作中 同步改变原来的Set结构 目前没有直接的方法 但有两种变通的方法
    // 方法一 利用原Set结构映射出一个新的结构 然后赋值给原Set结构
    let set = new Set([1, 2, 3]);
    set = new Set([...set].map(val => val * 2));
    // set的值是2, 4, 6

    // 方法二 利用Array.from
    let set = new Set([1, 2, 3]);
    set = new Set(Array.from(set, val => val * 2));
    // set的值是2, 4, 6


</script>